home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
graphic
/
pvquan16.zip
/
QUANT
/
FILES.C
next >
Wrap
C/C++ Source or Header
|
1992-11-30
|
11KB
|
347 lines
/************************************************************************
* *
* Copyright (c) 1991, Frank van der Hulst *
* All Rights Reserved *
* *
* Authors: *
* FvdH - Frank van der Hulst (Wellington, NZ) *
* *
* Versions: *
* V1.1 910626 FvdH - QUANT released for DBW_RENDER *
* V1.2 911021 FvdH - QUANT released for PoV Ray *
* V1.3 911030 FvdH - Added 320x200x256x4 pages support *
* - Fixed bug in output_anim_files *
* V1.4 920303 FvdH - Ported to GNU C *
* V1.5 920331 FvdH - Allow Targa input *
* 920403 FvdH - Allow any number of files *
* V1.6 921023 FvdH - Produce multi-image GIFs *
* - Port to OS/2 IBM C Set/2 *
* *
************************************************************************/
#include <string.h>
#ifdef __TURBOC__
#include <dos.h>
#define SC_INDEX 0x3c4
#define MAP_MASK 2
#endif
#ifdef __GNUC__
#define SEEK_SET 0
#endif
#include "gif_lib.h"
#include "quant.h"
int (*get_pixel)(UCHAR *pixel);
static FILE *out_file;
static FILE *in_file[3];
static int get_pixel_raw(UCHAR *pixel)
{
int t;
#if INPUT_BITS == 8
if ((t = getc(in_file[2])) == EOF) return FALSE;
pixel[BLUE] = t;
if ((t = getc(in_file[1])) == EOF) return FALSE;
pixel[GREEN] = t;
if ((t = getc(in_file[0])) == EOF) return FALSE;
pixel[RED] = t;
#else
#define MAX_IN ((0xff << (8 - INPUT_BITS)) & 0xff)
#define ROUND (1 << (7 - INPUT_BITS))
#define R_SHIFT (8 - INPUT_BITS)
if ((t = getc(in_file[2])) == EOF) return FALSE;
pixel[BLUE] = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
if ((t = getc(in_file[1])) == EOF) return FALSE;
pixel[GREEN] = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
if ((t = getc(in_file[0])) == EOF) return FALSE;
pixel[RED] = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
#undef MAX_IN
#undef ROUND
#undef R_SHIFT
#endif
return TRUE;
}
static int get_pixel_targa(UCHAR *pixel)
{
int t;
#if INPUT_BITS == 8
if ((t = getc(in_file[0])) == EOF) return FALSE;
pixel[BLUE] = t;
if ((t = getc(in_file[0])) == EOF) return FALSE;
pixel[GREEN] = t;
if ((t = getc(in_file[0])) == EOF) return FALSE;
pixel[RED] = t;
#else
#define MAX_IN ((0xff << (8 - INPUT_BITS)) & 0xff)
#define ROUND (1 << (7 - INPUT_BITS))
#define R_SHIFT (8 - INPUT_BITS)
if ((t = getc(in_file[0])) == EOF) return FALSE;
pixel[BLUE] = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
if ((t = getc(in_file[0])) == EOF) return FALSE;
pixel[GREEN] = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
if ((t = getc(in_file[0])) == EOF) return FALSE;
pixel[RED] = t < MAX_IN ? (t + ROUND) >> R_SHIFT : t >> R_SHIFT;
#undef MAX_IN
#undef ROUND
#undef R_SHIFT
#endif
return TRUE;
}
/* The "+ft" option of PVRAY writes out Targa format. Specifically, the
fields are:
Header:
00 00 02 00 00 - Fixed header information for uncompressed type 2 image
00 00 00
0000 - Horizontal offset always is at 0000
llll - Vertical offset (1st line number, 16 bits, LSB first)
wwww hhhh - width, height of image (16 bits each, LSB first)
18 20 - 24 bits per pixel, Top-down raster
For each line:
bb gg rr bb gg rr ... - blue, green, and red data, 8 bits for each pixel.
*/
void open_file(char *fname, int num)
{
char filename[256];
if (input_type == 0) {
sprintf(filename, "%s_%d.red", fname, num);
if ((in_file[0] = fopen(filename, "rb")) == NULL) {
printf("Cannot open %s.\n", filename);
err_exit();
}
sprintf(filename, "%s_%d.grn", fname, num);
if ((in_file[1] = fopen(filename, "rb")) == NULL) {
printf("Cannot open %s.\n", filename);
err_exit();
}
sprintf(filename, "%s_%d.blu", fname, num);
if ((in_file[2] = fopen(filename, "rb")) == NULL) {
printf("Cannot open %s.\n", filename);
err_exit();
}
get_pixel = get_pixel_raw;
return;
}
if (input_type == 1) {
sprintf(filename, "%s_%d.tga", fname, num);
if ((in_file[0] = fopen(filename, "rb")) == NULL) {
printf("Cannot open %s.\n", filename);
err_exit();
}
fseek(in_file[0], 18, SEEK_SET); /* Skip header */
get_pixel = get_pixel_targa;
return;
}
}
void close_file(void)
{
fclose(in_file[0]);
if (input_type == 0) {
fclose(in_file[1]);
fclose(in_file[2]);
}
}
void write_4_planes(char *infname, int num, UINT Xres, UINT Yres)
{
UINT plane, x, y;
UCHAR pixel[3];
char more_data;
char dummy[3];
#ifdef __TURBOC__
char far *VGA_addr = MK_FP(0xa000,0);
#endif
open_file(infname, num);
for (plane = 0; plane < 4; plane++) {
more_data = 1;
fseek(in_file[0], (long)plane, SEEK_SET);
fseek(in_file[1], (long)plane, SEEK_SET);
fseek(in_file[2], (long)plane, SEEK_SET);
#ifdef __TURBOC__
if (disp_image) outport(SC_INDEX, (0x100 << plane) | MAP_MASK);
#endif
for (y = 0; y < Yres; y++) {
for (x = plane; x < Xres; x += 4) {
if (more_data) {
if (!get_pixel(pixel))
pixel[RED] = pixel[GREEN] = pixel[BLUE] = more_data = 0;
else {
fread(dummy, 3, 1, in_file[0]); /* Skip to next pixel for this plane */
fread(dummy, 3, 1, in_file[1]);
fread(dummy, 3, 1, in_file[2]);
}
putc(pal_index(pixel), out_file);
#ifdef __TURBOC__
if (disp_image) *VGA_addr++ = pal_index(pixel);
#endif
} else putc(pal_index(pixel), out_file);
}
}
}
close_file();
}
static void write_linear(char *infname, int num, UINT Xres, UINT Yres)
{
UINT x, y;
UCHAR pixel[3];
char more_data;
#ifdef __TURBOC__
char far *VGA_addr = MK_FP(0xa000,0);
#endif
open_file(infname, num);
more_data = 1;
for (y = 0; y < Yres; y++) {
for (x = 0; x < Xres; x++) {
if (more_data) {
if (!get_pixel(pixel))
pixel[RED] = pixel[GREEN] = pixel[BLUE] = more_data = 0;
}
putc(pal_index(pixel), out_file);
#ifdef __TURBOC__
if (disp_image) {
outport(SC_INDEX, (0x100 << (x & 3)) | MAP_MASK);
VGA_addr[y*(320/4)+x/4] = pal_index(pixel);
}
#endif
}
}
close_file();
}
/****************************************************************************
Convert Raw image (One byte per pixel) into Gif file. Raw data is read
from in_file, and Gif is dumped to out_fname. ImageWidth times ImageHeight
bytes are read. Color map is dumped from ColorMap.
*/
static void output_gif_file(char *infname, int num_files, char *out_fname, UINT Xres, UINT Yres, UINT num_colours)
{
int i, x, y;
UCHAR pixel[3];
UCHAR *ScanLine;
for (i = 0; i < 8 && (2 << i) < num_colours; i++);
num_colours = 2 << i;
if (num_colours > 256) {
printf("Colour map must be less than 256 colours.\n");
err_exit();
}
printf("\nImage size is %dx%d: ", Xres, Yres);
if (EGifOpenFileName(out_fname) == -1) return;
EGifPutScreenDesc(Xres, Yres, 6, 0, 8, palette);
for (i = 0; i < num_files ; i++) {
open_file(infname, i);
EGifPutImageDesc(0, 0, Xres, Yres, 8);
CHECK_ALLOC(ScanLine, UCHAR, Xres, "Scan Line");
/* Here it is - get one raw line from input file, and dump to Gif: */
for (y = 0; y < Yres; y++) {
/* Note we assume here PixelSize == Byte, which is not necessarily */
/* so. If not - must read one byte at a time, and coerce to pixel. */
for (x = 0